package com.share.device.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.share.common.security.utils.SecurityUtils;
import com.share.device.domain.Cabinet;
import com.share.device.domain.CabinetSlot;
import com.share.device.domain.CabinetType;
import com.share.device.domain.PowerBank;
import com.share.device.mapper.CabinetMapper;
import com.share.device.mapper.CabinetSlotMapper;
import com.share.device.mapper.CabinetTypeMapper;
import com.share.device.mapper.PowerBankMapper;
import com.share.device.service.ICabinetService;
import com.share.device.service.ICabinetSlotService;
import com.share.device.service.IPowerBankService;
import com.share.order.domain.OrderInfo;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.nio.file.Watchable;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class CabinetServiceImpl extends ServiceImpl<CabinetMapper, Cabinet>
        implements ICabinetService {

    @Autowired
    private CabinetMapper cabinetMapper;

    @Autowired
    private CabinetSlotMapper cabinetSlotMapper;

    @Autowired
    private IPowerBankService powerBankService;

    @Autowired
    private ICabinetSlotService cabinetSlotService;

    @Autowired
    private CabinetTypeMapper cabinetTypeMapper;

    //分页查询
    @Override
    public List<Cabinet> selectListCabinet(Cabinet cabinet) {
        return cabinetMapper.selectListCabinet(cabinet);
    }

    //未使用柜机
    @Override
    public List<Cabinet> searchNoUseList(String keyword) {
        LambdaQueryWrapper<Cabinet> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(Cabinet::getCabinetNo,keyword);
        wrapper.eq(Cabinet::getStatus,0);
        List<Cabinet> list = cabinetMapper.selectList(wrapper);
        return list;
    }

    @Override
    public Cabinet getBtCabinetNo(String cabinetNo) {
        return cabinetMapper.selectOne(new LambdaQueryWrapper<Cabinet>().eq(Cabinet::getCabinetNo, cabinetNo));
    }


    @Override
    public Map<String, Object> getAllInfo(Long id) {
        // 查询柜机信息
        Cabinet cabinet = this.getById(id);

        // 查询插槽信息
        List<CabinetSlot> cabinetSlotList = cabinetSlotMapper.selectList(new LambdaQueryWrapper<CabinetSlot>().eq(CabinetSlot::getCabinetId, cabinet.getId()));
        // 获取可用充电宝id列表
        List<Long> powerBankIdList = cabinetSlotList.stream().filter(item -> null != item.getPowerBankId()).map(CabinetSlot::getPowerBankId).collect(Collectors.toList());
        if(!CollectionUtils.isEmpty(powerBankIdList)) {
            List<PowerBank> powerBankList = powerBankService.listByIds(powerBankIdList);
            Map<Long,PowerBank> powerBankIdToPowerBankMap = powerBankList.stream().collect(Collectors.toMap(PowerBank::getId, PowerBank -> PowerBank));
            cabinetSlotList.forEach(item -> item.setPowerBank(powerBankIdToPowerBankMap.get(item.getPowerBankId())));
        }

        Map<String, Object> result = Map.of("cabinet", cabinet, "cabinetSlotList", cabinetSlotList);
        return result;
    }

    @Override
    public Cabinet getAllInfoByCabinetNo(String cabinetNo) {
        Cabinet cabinet = cabinetMapper.selectOne(new LambdaQueryWrapper<Cabinet>().eq(Cabinet::getCabinetNo, cabinetNo));
        return cabinet;
    }

    @Override
    public void updateCabinetNo(String cabinetNo) {
        Long channelId = cabinetMapper.selectOne(new LambdaQueryWrapper<Cabinet>().eq(Cabinet::getCabinetNo, cabinetNo)).getId();
        List<CabinetSlot> list = cabinetSlotService.list(new LambdaQueryWrapper<CabinetSlot>().eq(CabinetSlot::getCabinetId, channelId));
        int count = 0;
        if(!list.isEmpty()){
            for (CabinetSlot item : list) {
                Long powerBankId = item.getPowerBankId();
                if(powerBankId != null) {
                    count ++;
                }
            }
        }
        Cabinet cabinet = new Cabinet();
        cabinet.setId(channelId);
        cabinet.setAvailableNum(count);
        cabinetMapper.updateById(cabinet);
    }

    @Override
    public Integer addCabinet(Cabinet cabinet) {
        CabinetType cabinetType = cabinetTypeMapper.selectById(cabinet.getCabinetTypeId());
        cabinet.setTotalSlots(cabinetType.getTotalSlots());
        cabinet.setFreeSlots(cabinetType.getTotalSlots());
        cabinet.setAvailableNum(0);
        return cabinetMapper.insert(cabinet);
    }

    @Override
    public Map<String, Object> getDeviceStatistics() {
        // 获取设备总数
        long totalCount = this.count();
        
        // 获取正在使用的设备数量（状态为1的设备）
        long usedCount = this.count(new LambdaQueryWrapper<Cabinet>()
                .eq(Cabinet::getStatus, 1));
        
        // 计算使用率
        double usageRate = totalCount > 0 ? (double) usedCount / totalCount * 100 : 0;
        
        return Map.of(
            "totalCount", totalCount,
            "usageRate", Math.round(usageRate * 100.0) / 100.0
        );
    }

    @Override
    @Transactional()
    public Integer addSlot(CabinetSlot cabinet) {
        if(cabinet.getPowerBankId() != null){
            cabinet.setStatus("1");
            cabinet.setDelFlag("0");
            cabinetSlotMapper.insert(cabinet);
            Long l = cabinetMapper.selectCount(new LambdaQueryWrapper<Cabinet>().eq(Cabinet::getId, cabinet.getCabinetId()));
            Cabinet cabinet1 = cabinetMapper.selectById(cabinet.getCabinetId());
            CabinetType cabinetType = cabinetTypeMapper.selectById(cabinet1.getCabinetTypeId());
            LambdaUpdateWrapper<Cabinet> set1 = new LambdaUpdateWrapper<Cabinet>()
                    .eq(Cabinet::getId, cabinet.getCabinetId())
                    .set(Cabinet::getFreeSlots, cabinetType.getTotalSlots()-l)
                    .set(Cabinet::getUsedSlots, l)
                    .set(Cabinet::getAvailableNum
                    ,l);
            cabinetMapper.update(null,set1);
            LambdaUpdateWrapper<PowerBank> set
                    = new LambdaUpdateWrapper<PowerBank>()
                    .eq(PowerBank::getId, cabinet.getPowerBankId())
                    .set(PowerBank::getStatus, "1");
            powerBankService.update(null,set);
            return 1;
        }
        return null;
    }
}
